'''
Created on 2009-7-16

@author: roy
'''

import time
import urllib
import urllib2
import httplib
import cookielib
from util import *
from constant import *

from google.appengine.api import urlfetch

class SmartRedirectHandler(urllib2.HTTPRedirectHandler):   
    """Handle the redirect response when return the HTTP code of 301, 302."""
    def http_error_301(cls, req, fp, code, msg, headers):  
        result = urllib2.HTTPRedirectHandler.http_error_301(cls, req, fp, code, msg, headers)              
        result.status = code                                
        return result                                       

    def http_error_302(cls, req, fp, code, msg, headers):  
        result = urllib2.HTTPRedirectHandler.http_error_302(cls, req, fp, code, msg, headers)              
        result.status = code      
        return result  



class httpHelper:
    '''
    This is a class to handle any http related operation
    '''

    def __init__(self):
        '''
        Constructor
        '''
        self.opener = None
 
       
    def get_opener(self):
        if self.opener==None:
            self.cookies = urllib2.HTTPCookieProcessor(cookielib.CookieJar())
            self.opener = urllib2.build_opener(self.cookies, SmartRedirectHandler())
        return self.opener


    def login(self, append_url, data):
        '''
        post user, pass to get verify code
        return the verify code
        '''
        opener = self.get_opener()
        
        url = urllib.basejoin(urlRoot, append_url)
        
        #url = append_url
        
        request = urllib2.Request(url, urllib.urlencode(data))
            
        debug('--http read page %s --' % append_url)
        
        f = opener.open(request)
        
        debug( '%s, %s' % (f.code,  f.info()))
        debug(f.url)
        debug(f.read())
        
        return encode_str(f.geturl())
    
        
    def read_page(self, append_url, method='GET', data=None):
        '''Request the specified address from cookies to get the page content.'''
        try:
            timeout_sec = 5
            sleep_count = 0
            sleep_per_sec = 2
            
            opener = self.get_opener()
            
            url = urllib.basejoin(urlRoot, append_url)
            
            #url = append_url
            
            if method == 'GET':
                request = urllib2.Request(url)
            elif method == 'POST':
                request = urllib2.Request(url, urllib.urlencode(data))
                
            #debug('--http read page %s --' % append_url)
            f = opener.open(request)
            while True:
                indexStr = f.read()
                if len(indexStr) != 0:
                    break;
                
                # TODO timeout read from conf
                sleep_count += 1
                #debug('-- http read sleep --')
                time.sleep(sleep_per_sec);
                if sleep_per_sec * sleep_count > timeout_sec:
                    break;
            
            return encode_str(indexStr)
        except:
            return '' 
    
    
class httpHelper_httplib:
    '''
    This is a class to handle any http related operation
    '''

    def __init__(self):
        '''
        Constructor
        '''
        self.opener = None
        self.cookies = ''
        #self.conn = httplib.HTTPConnection(wapHost)
        
    
    def login(self, append_url, data):
        
        conn = httplib.HTTPConnection(wapHost)
        headers = dict()
        headers['Content-type'] = 'application/x-www-form-urlencoded'
        conn.request('POST', append_url, 
                         urllib.urlencode(data),
                         headers)
        resp = conn.getresponse()
        
        debug(resp)
        debug(resp.getheaders())
        debug(resp.msg)
        debug(resp.read())
        
        str = resp.getheader('Location')
        conn.close()
        return str
    
    
    def read_page(self, append_url, method='GET', data=None):
        timeout_sec = 20
        sleep_count = 0
        sleep_per_sec = 3
        
        conn = httplib.HTTPConnection(wapHost)
        
        headers = dict()
        
        #url = append_url
        
        #debug('url=%s, method=%s' % (append_url, method))
        
        if method == 'GET':
            conn.request('GET', append_url)
        else:
            headers['Content-type'] = 'application/x-www-form-urlencoded'
            conn.request('POST', append_url, 
                         urllib.urlencode(data),
                         headers)
            
        resp = conn.getresponse()

        while True:
            indexStr = resp.read()
            if len(indexStr) != 0:
                break;
            
            # TODO timeout read from conf
            sleep_count += 1
            #debug('-- http read sleep --')
            time.sleep(sleep_per_sec);
            if sleep_per_sec * sleep_count > timeout_sec:
                break;
            
        conn.close()
        return encode_str(indexStr)
        
#===============================================================================
#    def __getResponse(self, append_url, method='GET', data=None):
#        headers = dict()
#        headers['Keep-Alive'] = '300'
#        headers['User-Agent'] = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.11) Gecko/2009060215 Firefox/3.0.11 (.NET CLR 3.5.30729)'
#        headers['Connection'] = 'keep-alive'
#            
#        if validCookie(self.cookies):
#                headers['Cookie'] = self.cookies
#                    
#        if method == 'GET':
#            self.conn.request('GET', append_url, None, headers)
#        else:
#            headers['Content-type'] = 'application/x-www-form-urlencoded'
#            self.conn.request('POST', append_url, 
#                         urllib.urlencode(data),
#                         headers)
#        resp = self.conn.getresponse()
#        return resp
#===============================================================================
            
        
#===============================================================================
#    def read_page(self, append_url, method='GET', data=None):
#        #'''Request the specified address from cookies to get the page content.'''
#        
#        #try:
#            timeout_sec = 20
#            sleep_count = 0
#            sleep_per_sec = 3
#            content = ''
#                
#            resp = self.__getResponse(append_url, method, data)
#                
#            str = resp.getheader('Set-Cookie')
#            if validCookie(str):
#                self.cookies = str
# 
#            str = resp.getheader('Location')
#            if (str != None) and (str != ''):
#                resp = self.__getResponse(str)
#                    
#            str = resp.getheader('Content-Length')
#            if (str != '') and (str == '0'):
#                return ''
#            
#            while True:
#                content = resp.read()
#                if len(content) != 0:
#                    break;
#                  
#                # TODO timeout read from conf
#                sleep_count += 1
#                debug('-- http read sleep --')
#                time.sleep(sleep_per_sec);
#                if sleep_per_sec * sleep_count > timeout_sec:
#                    break;
#                
#            self.conn.close()
#            return encode_str(content)
# #===============================================================================
# #        except:
# #            log('http error')
# #            return ''
# #        finally:
# #===============================================================================
#            self.conn.close()
#===============================================================================
        
class httpHelper_urlfetch:
    '''
    implement http by url of google appengine fetch 
    '''
    def __init__(self):
        pass
    
    
    def read_page(self, append_url, method='GET', data=None):
        try:
            url = urllib.basejoin(urlRoot, append_url)
            
            #log(url)
                
            if method == 'GET':
                result = urlfetch.fetch(url=url,
                                        deadline = 10)
            elif method == 'POST':
                form_data = urllib.urlencode(data)
                result = urlfetch.fetch(url=url,
                                        payload=form_data,
                                        method=urlfetch.POST,
                                        follow_redirects=False,
                                        deadline = 10,
                                        headers={'Content-Type': 'application/x-www-form-urlencoded'})
            if (result.content != None):
                #log(result.content)
                return result.content.decode('utf-8')
            else:
                return ''
        except urlfetch.DownloadError:
            log('urlfetch download error')
            return ''
        except urlfetch.InvalidURLError:
            log('urlfetch invalid url error')
            return ''
        except urlfetch.ResponseTooLargeError:
            log('urlfetch response too large error')
            return ''
        except:
            log('urlfetch error')
            return ''

    
def test():
    pass
    
   
    
#===============================================================================
#    http = httpHelper_httplib()
#    
#    #str = http.read_page('http://www.kaixin001.com/login/login.php', 
#    str = http.read_page('/login/login.php', 'POST', user_data)
#    print str
#    
#    print '-'*20
#    
#    str = http.read_page('/home/')
#    print str
#===============================================================================
    
    
if __name__ == '__main__':
    test()       
    
        